using DDD.Application.Interfaces;
using DDD.Application.ViewModels;
using DDD.Domain.Core.Bus;
using DDD.Domain.Core.Notifications;
using DDD.Infra.CrossCutting.Identity.Authorization;

using MediatR;

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace DDD.Services.Api.Controllers.V1;

[Authorize]
[ApiVersion("1.0")]
public class CustomerController : ApiController
{
    private readonly ICustomerAppService _customerAppService;

    public CustomerController(
        ICustomerAppService customerAppService,
        INotificationHandler<DomainNotification> notifications,
        IMediatorHandler mediator)
        : base(notifications, mediator)
    {
        _customerAppService = customerAppService;
    }

    [HttpGet]
    [AllowAnonymous]
    [Route("customer-management")]
    public IActionResult Get()
    {
        return Response(_customerAppService.GetAll());
    }

    [HttpGet]
    [AllowAnonymous]
    [Route("customer-management/{id:guid}")]
    public IActionResult Get(Guid id)
    {
        var customerViewModel = _customerAppService.GetById(id);

        return Response(customerViewModel);
    }

    [HttpPost]
    [Authorize(Policy = "CanWriteCustomerData", Roles = Roles.Admin)]
    [Route("customer-management")]
    public IActionResult Post([FromBody] CustomerViewModel customerViewModel)
    {
        if (!ModelState.IsValid)
        {
            NotifyModelStateErrors();
            return Response(customerViewModel);
        }

        _customerAppService.Register(customerViewModel);

        return Response(customerViewModel);
    }

    [HttpPut]
    [Authorize(Policy = "CanWriteCustomerData", Roles = Roles.Admin)]
    [Route("customer-management")]
    public IActionResult Put([FromBody] CustomerViewModel customerViewModel)
    {
        if (!ModelState.IsValid)
        {
            NotifyModelStateErrors();
            return Response(customerViewModel);
        }

        _customerAppService.Update(customerViewModel);

        return Response(customerViewModel);
    }

    [HttpDelete]
    [Authorize(Policy = "CanRemoveCustomerData", Roles = Roles.Admin)]
    [Route("customer-management")]
    public IActionResult Delete(Guid id)
    {
        _customerAppService.Remove(id);

        return Response();
    }

    [HttpGet]
    [AllowAnonymous]
    [Route("customer-management/history/{id:guid}")]
    public IActionResult History(Guid id)
    {
        var customerHistoryData = _customerAppService.GetAllHistory(id);
        return Response(customerHistoryData);
    }

    [HttpGet]
    [AllowAnonymous]
    [Route("customer-management/pagination")]
    public IActionResult Pagination(int skip, int take)
    {
        return Response(_customerAppService.GetAll(skip, take));
    }
}
